package com.sunwayworld.basemodule.rm.client.io;

import com.sunwayworld.baseline.framework.override.LimsExcelHelper;
import com.sunwayworld.basemodule.rm.client.bean.LimsClientBean;
import com.sunwayworld.basemodule.rm.client.service.LimsClientService;
import com.sunwayworld.cloud.module.item.admarea.bean.CoreAdmAreaBean;
import com.sunwayworld.cloud.module.item.admarea.service.CoreAdmAreaService;
import com.sunwayworld.framework.context.ApplicationContextHelper;
import com.sunwayworld.framework.exception.InvalidDataException;
import com.sunwayworld.framework.i18n.I18nHelper;
import com.sunwayworld.framework.io.file.FilePathDTO;
import com.sunwayworld.framework.io.file.FilePathManager;
import com.sunwayworld.framework.mybatis.mapper.MatchPattern;
import com.sunwayworld.framework.mybatis.mapper.SearchFilter;
import com.sunwayworld.framework.spring.annotation.GikamBean;
import com.sunwayworld.framework.utils.BeanUtils;
import com.sunwayworld.framework.utils.CollectionUtils;
import com.sunwayworld.framework.utils.StringUtils;
import com.sunwayworld.module.item.file.bean.CoreFileBean;
import com.sunwayworld.module.item.file.bean.CoreFileImportResultDTO;
import com.sunwayworld.module.item.file.function.CoreFileImportFunction;
import com.sunwayworld.module.item.file.utils.CoreFileUtils;
import com.sunwayworld.module.sys.code.bean.CoreCodeBean;
import com.sunwayworld.module.sys.code.service.CoreCodeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@GikamBean
@Component(value = "LimsClientImportFileFunction")
public class LimsClientImportFileFunction implements CoreFileImportFunction {

    @Autowired
    @Lazy
    private CoreCodeService coreCodeService;

    @Autowired
    @Lazy
    LimsClientService limsClientService;

    @Autowired
    @Lazy
    CoreAdmAreaService admAreaService;

    // 标题行所在索引
    private static final int titleRowIndex = 1;

    @Override
    @Transactional
    public CoreFileImportResultDTO apply(CoreFileBean coreFileBean) {
        CoreFileImportResultDTO resultDTO = new CoreFileImportResultDTO();
        List<LimsClientBean> clientBeans = LimsExcelHelper.readDataFromExcel(FilePathManager.getLocalPath(CoreFileUtils.toFilePath(coreFileBean)).toString(), titleRowIndex, titleRowIndex + 1, LimsClientBean.class);
        if (clientBeans.isEmpty()) {
            throw new InvalidDataException("导入失败！");
        }
        List<String> columns = Arrays.asList("clientCode","password","clientName", "clientType");
        List<String> colNames = Arrays.asList("【客户编号】", "【客户密码】", "【客户名称】", "【客户类型】");
        // 客户编码唯一
        List<LimsClientBean> oriCLients = limsClientService.selectAll();
        // 客户类型
        List<CoreCodeBean> customerTypes = coreCodeService.selectListByFilter(SearchFilter.instance().match("codeCategoryId", "customerType").filter(MatchPattern.EQ));
        // 区域
        List<CoreCodeBean> largeAreas = coreCodeService.selectListByFilter(SearchFilter.instance().match("codeCategoryId", "largeArea").filter(MatchPattern.EQ));
        // 省份
        List<CoreAdmAreaBean> provices = admAreaService.selectListByFilter(SearchFilter.instance()
            .match("PARENTID", null).filter(MatchPattern.EQ));
        // 城市
        List<String> provinceIds = provices.stream().map(CoreAdmAreaBean::getId).collect(Collectors.toList());
        List<CoreAdmAreaBean> citys = admAreaService.selectListByFilter(SearchFilter.instance()
            .match("PARENTID", provinceIds).filter(MatchPattern.OR));
        // 联系电话格式校验
        String phonePattern = "^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\\d{8}|^(0\\d{2,3})-?(\\d{7,8})$";
        // 联系邮箱格式校验
        String emailPattern = "^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$";
        // 导入的客户编码池
        List<String> clientCodes = new ArrayList<>();
        clientBeans.stream().filter(Objects::nonNull).forEach(s -> {
            StringBuilder msg = new StringBuilder();
            for (int i = 0; i < columns.size(); i++) {
                Object value = BeanUtils.getPropertyValue(s, columns.get(i));
                if (value == null || (value.getClass().equals(String.class) && value.equals(""))) {
                    msg.append(colNames.get(i));
                }
            }
            if (msg.length() > 0) {
                msg.append(" 为必填项；");
            }
            if (msg.length() > 0) {
                if (!StringUtils.isBlank(s.getExt$Item("validateimpmsg"))) {
                    s.setExt$Item("validateimpmsg", s.getExt$Item("validateimpmsg").concat(msg.toString()));
                } else {
                    s.setExt$Item("validateimpmsg", msg.toString());
                }
            }
            // 客户编码不能和现有数据重复
            if (!CollectionUtils.isEmpty(oriCLients)) {
                Optional<LimsClientBean> optional =
                    oriCLients.stream().filter(g -> g.getClientCode().equals(s.getClientCode())).findAny();
                if (optional.isPresent()) {
                    if (!StringUtils.isBlank(s.getExt$Item("validateimpmsg"))) {
                        s.setExt$Item("validateimpmsg", s.getExt$Item("validateimpmsg").concat("【客户编码】在LIMS已存在；"));
                    } else {
                        s.setExt$Item("validateimpmsg", "【客户编码】在LIMS已存在；");
                    }
                } else {
                    // 当前导入的数据，客户编码不能重复
                    if (clientCodes.contains(s.getClientCode())) {
                        if (!StringUtils.isBlank(s.getExt$Item("validateimpmsg"))) {
                            s.setExt$Item("validateimpmsg", s.getExt$Item("validateimpmsg").concat("【客户编码】重复；"));
                        } else {
                            s.setExt$Item("validateimpmsg", "【客户编码】重复；");
                        }
                    } else {
                        clientCodes.add(s.getClientCode());
                    }
                }
            }
            // 客户类型
            if (!StringUtils.isBlank(s.getClientType())) {
                Optional<CoreCodeBean> optional = customerTypes.stream().filter(g -> g.getCodeName().equals(s.getClientType())).findAny();
                if (optional.isPresent()) {
                    s.setClientType(optional.get().getCode());
                } else {
                    if (!StringUtils.isBlank(s.getExt$Item("validateimpmsg"))) {
                        s.setExt$Item("validateimpmsg", s.getExt$Item("validateimpmsg").concat("【客户类型】无法识别；"));
                    } else {
                        s.setExt$Item("validateimpmsg", "【客户类型】无法识别；");
                    }
                }
            }
            // 区域
            if (!StringUtils.isBlank(s.getLargeArea())) {
                Optional<CoreCodeBean> optional = largeAreas.stream().filter(g -> g.getCodeName().equals(s.getLargeArea())).findAny();
                if (optional.isPresent()) {
                    s.setLargeArea(optional.get().getCode());
                } else {
                    if (!StringUtils.isBlank(s.getExt$Item("validateimpmsg"))) {
                        s.setExt$Item("validateimpmsg", s.getExt$Item("validateimpmsg").concat("【区域】无法识别；"));
                    } else {
                        s.setExt$Item("validateimpmsg", "【区域】无法识别；");
                    }
                }
            }
            // 省份
            if (!StringUtils.isBlank(s.getProvince())) {
                Optional<CoreAdmAreaBean> optional = provices.stream().filter(g -> g.getAdmAreaName().equals(s.getProvince())).findAny();
                if (optional.isPresent()) {
                    s.setProvince(optional.get().getAdmAreaName());
                } else {
                    if (!StringUtils.isBlank(s.getExt$Item("validateimpmsg"))) {
                        s.setExt$Item("validateimpmsg", s.getExt$Item("validateimpmsg").concat("【省份】无法识别；"));
                    } else {
                        s.setExt$Item("validateimpmsg", "【省份】无法识别；");
                    }
                }
            }
            // 城市必须属于省份下
            if (!StringUtils.isBlank(s.getCity())) {
                // 选择了城市，省份必选
                if (StringUtils.isBlank(s.getProvince())) {
                    if (!StringUtils.isBlank(s.getExt$Item("validateimpmsg"))) {
                        s.setExt$Item("validateimpmsg", s.getExt$Item("validateimpmsg").concat("【省份】不能为空；"));
                    } else {
                        s.setExt$Item("validateimpmsg", "【省份】不能为空；");
                    }
                } else {
                    Optional<CoreAdmAreaBean> optionalProvince = provices.stream().filter(g -> g.getAdmAreaName().equals(s.getProvince())).findAny();
                    if (optionalProvince.isPresent()) {
                        String provinceId = optionalProvince.get().getId();
                        // 省份存在
                        // 城市必须属于省份
                        Optional<CoreAdmAreaBean> optionalCity = citys.stream().filter(g ->
                            g.getAdmAreaName().equals(s.getCity())
                            && StringUtils.equals(g.getParentId(), provinceId)).findAny();
                        if (optionalCity.isPresent()) {
                            s.setCity(optionalCity.get().getAdmAreaName());
                        } else {
                            if (!StringUtils.isBlank(s.getExt$Item("validateimpmsg"))) {
                                s.setExt$Item("validateimpmsg", s.getExt$Item("validateimpmsg").concat("【城市】错误；"));
                            } else {
                                s.setExt$Item("validateimpmsg", "【城市】错误；");
                            }
                        }
                    }
                }
            }
            // 联系电话
            if (!StringUtils.isBlank(s.getContactPhone()) && !s.getContactPhone().matches(phonePattern)) {
                if (!StringUtils.isBlank(s.getExt$Item("validateimpmsg"))) {
                    s.setExt$Item("validateimpmsg", s.getExt$Item("validateimpmsg").concat("【联系电话】格式不正确；"));
                } else {
                    s.setExt$Item("validateimpmsg", "【联系电话】格式不正确；");
                }
            }
            // 联系邮箱
            if (!StringUtils.isBlank(s.getContactEmail()) && !s.getContactEmail().matches(emailPattern)) {
                if (!StringUtils.isBlank(s.getExt$Item("validateimpmsg"))) {
                    s.setExt$Item("validateimpmsg", s.getExt$Item("validateimpmsg").concat("【联系邮箱】格式不正确；"));
                } else {
                    s.setExt$Item("validateimpmsg", "【联系邮箱】格式不正确；");
                }
            }
            s.setId(ApplicationContextHelper.getNextIdentity());
        });
        // 返还校验结果
        if (clientBeans.stream().anyMatch(i -> !StringUtils.isEmpty(i.getExt$Item("validateimpmsg")))) {
            FilePathDTO fr = CoreFileUtils.toFilePath(coreFileBean);
            FilePathDTO filePathDTO = LimsExcelHelper.writeImportFailureListAsExcel(FilePathManager.getLocalPath(fr).toString(), clientBeans, titleRowIndex, titleRowIndex + 1, "导入错误信息.xlsx", false);
            resultDTO.setUrl(FilePathManager.getUrl(filePathDTO));
            resultDTO.setMessage("导入失败");
            return resultDTO;
        }
        limsClientService.getDao().insert(clientBeans);
        resultDTO.setMessage(I18nHelper.getMessage("CORE.MODULE.SYS.DPCONFIGS.TIP.IMPORT_SUCCESS"));
        return resultDTO;
    }

    @Override
    public boolean test(CoreFileBean coreFile, String service) {
        return true;
    }

}
